`timescale 1ns / 1ps

`include "defines.v"

module ysyx_210448_mem_stage (
    input clk,
    input wire rst,
    input wire [3:0] axi_r_id_i,
    input wire axi_mem_write,
    input wire axi_read_ready,
    input wire handshake_done,
    input wire mem_fetched,
    input wire mem_open,
    input wire mem_read,
    input wire stop,
    input wire wb_write,
    input wire [2:0]s3,
    input wire [63:0]mem_pc,
    input wire [31:0] mem_inst,
    input wire [4:0] mem_rd,
    input wire [6:0]mem_opcode,
    input wire [6:0] exe_opcode,
    input wire [6 : 0]mem_s_imm,
    input wire [4 : 0]mem_s_imm_s,
    input wire [63:0]mem_op1,
    input wire [63:0]mem_op2,
    input wire [11:0] mem_I_imm,
    input wire [2:0] mem_s1,
    output reg mem_write,
    input wire wb_write_ready,
    input wire b_hs,
    output wire [63:0] mem_read_addr,
    input wire [63:0] rdata,
    output wire [63:0] mem_write_addr,
    output reg [63:0] wdata,
    output reg [7:0] wmask,
    output wire mem_write_ready,
    output reg[63:0] mem_read_data,
    input wire mem_wb_en,
    output wire [3:0]mem_read_id
    
);
reg [11:0]s_s;
reg [63:0] mem_data;
//wire mem_write_ready;
assign mem_read_id=4'b0001;
//判断取的是哪个字节
reg [2:0] s4;
reg [2:0] s5;
//wire [2:0] s3;
//预处理写的值，读的地址
//把exe阶段的处理到这里
//单周期时总是慢一拍，猜测是exe阶段延时

assign mem_write_ready=(axi_mem_write&&mem_fetched)?((wb_write_ready)?0:1):0;
assign s4=mem_write_addr[2:0];
reg [11:0] mem_I_imm_I;
assign mem_read_addr=mem_op1+{{52{mem_I_imm[11]}},mem_I_imm};
assign mem_write_addr=mem_op1+{{52{s_s[11]}},s_s};
assign s_s={mem_s_imm,mem_s_imm_s};
assign mem_data=mem_op2;

always @(posedge clk) begin
  if(rst)
  begin
    mem_write<=1'b0;
  end
  else
  begin
  if(mem_write_ready)
  begin
    mem_write<=1'b1;
  end
  else if(b_hs)
  begin
    mem_write<=1'b0;
  end
  else
  begin
    mem_write<=mem_write;
  end
  end
end



always@(*) begin
if(mem_opcode==7'b0000011)
begin
    mem_read_data=`ZERO_WORD;
        if(mem_s1==3'b000)//lb
        begin
          if(s3==3'b000) begin
          mem_read_data={{56{rdata[7]}},rdata[7:0]}; end
          else if(s3==3'b001) begin
          mem_read_data={{56{rdata[15]}},rdata[15:8]}; end
          else if(s3==3'b010) begin
          mem_read_data={{56{rdata[23]}},rdata[23:16]}; end
          else if(s3==3'b011) begin
          mem_read_data={{56{rdata[31]}},rdata[31:24]}; end
          else if(s3==3'b100) begin
          mem_read_data={{56{rdata[39]}},rdata[39:32]}; end
          else if(s3==3'b101) begin
          mem_read_data={{56{rdata[47]}},rdata[47:40]}; end
          else if(s3==3'b110) begin
          mem_read_data={{56{rdata[55]}},rdata[55:48]}; end
          else if(s3==3'b111) begin
          mem_read_data={{56{rdata[63]}},rdata[63:56]}; end
        end
        else if(mem_s1==3'b001)//lh
        begin
          if(s3==3'b000) begin
          mem_read_data={{48{rdata[15]}},rdata[15:0]}; end
          else if(s3==3'b010) begin
          mem_read_data={{48{rdata[31]}},rdata[31:16]}; end
          else if(s3==3'b100) begin
          mem_read_data={{48{rdata[47]}},rdata[47:32]}; end
          else if(s3==3'b110) begin
          mem_read_data={{48{rdata[63]}},rdata[63:48]}; end
        end
        else if(mem_s1==3'b010)
        begin
          if(s3==3'b000) begin
          mem_read_data={{32{rdata[31]}},rdata[31:0]}; end
          else if(s3==3'b100) begin
          mem_read_data={{32{rdata[63]}},rdata[63:32]}; end//lw
        end
        else if(mem_s1==3'b110)
        begin
          if(s3==3'b000) begin
          mem_read_data={{32{1'b0}},rdata[31:0]}; end
          else if(s3==3'b100) begin
          mem_read_data={{32{1'b0}},rdata[63:32]}; end//lwu
        end
        else if(mem_s1==3'b100)//lbu
        begin
          if(s3==3'b000) begin
          mem_read_data={{56{1'b0}},rdata[7:0]}; end
          else if(s3==3'b001) begin
          mem_read_data={{56{1'b0}},rdata[15:8]}; end
          else if(s3==3'b010) begin
          mem_read_data={{56{1'b0}},rdata[23:16]}; end
          else if(s3==3'b011) begin
          mem_read_data={{56{1'b0}},rdata[31:24]}; end
          else if(s3==3'b100) begin
          mem_read_data={{56{1'b0}},rdata[39:32]}; end
          else if(s3==3'b101) begin
          mem_read_data={{56{1'b0}},rdata[47:40]}; end
          else if(s3==3'b110) begin
          mem_read_data={{56{1'b0}},rdata[55:48]}; end
          else if(s3==3'b111) begin
          mem_read_data={{56{1'b0}},rdata[63:56]}; end
        end
        else if(mem_s1==3'b101)////lhu
        begin
          if(s3==3'b000) begin
          mem_read_data={{48{1'b0}},rdata[15:0]}; end
          else if(s3==3'b010) begin
          mem_read_data={{48{1'b0}},rdata[31:16]}; end
          else if(s3==3'b100) begin
          mem_read_data={{48{1'b0}},rdata[47:32]}; end
          else if(s3==3'b110|s3==3'b000) begin
          mem_read_data={{48{1'b0}},rdata[63:48]}; end
        end
        else if(mem_s1==3'b011)
        begin
          mem_read_data=rdata;
        end
        else
        begin
          mem_read_data=`ZERO_WORD;
        end
end  
else begin
mem_read_data=`ZERO_WORD;
end
if(mem_opcode==7'b0100011)
begin
      wdata=`ZERO_WORD;  
      if(mem_s1==3'b000)///sb
      begin
      wdata={8{mem_data[7:0]}};
      if(s4==3'b000)begin
      wmask=8'b00000001;end
      else if(s4==3'b001)begin
      wmask=8'b00000010;end
      else if(s4==3'b010) begin
      wmask=8'b00000100;end
      else if(s4==3'b011) begin
      wmask=8'b00001000;end
      else if(s4==3'b100) begin
      wmask=8'b00010000;end
      else if(s4==3'b101) begin
      wmask=8'b00100000;end
      else if(s4==3'b110) begin
      wmask=8'b01000000;end
      else if(s4==3'b111) begin
      wmask=8'b10000000;end
      else begin
        wmask=`ZERO_8;
      end
      end
      else if(mem_s1==3'b001)//sh
      begin
      wdata={4{mem_data[15:0]}};
      if(s4==3'b000) begin
      wmask=8'b00000011; end
      else if(s4==3'b010) begin
      wmask=8'b00001100; end
      else if(s4==3'b100) begin
      wmask=8'b00110000;end
      else if(s4==3'b110) begin
      wmask=8'b11000000; end
      else begin
        wmask=`ZERO_8;
      end
      end
      else if(mem_s1==3'b010)//sw
      begin
      wdata={2{mem_data[31:0]}};
      if(s4==3'b000) begin
      wmask=8'b00001111; end
      else if(s4==3'b100) begin
      wmask=8'b11110000; end
      else begin
        wmask=`ZERO_8;
      end
      end
      else if(mem_s1==3'b011)//sd
      begin
        wdata=mem_data[63:0];
        wmask=8'b11111111;
      end
      else
      begin
      wdata=`ZERO_WORD;
      wmask=`ZERO_8;
      end
end
else
begin
  wdata=`ZERO_WORD;
  wmask=`ZERO_8;
end
end




endmodule
